package hamaster.jpbc.mgr;

import static hamaster.jpbc.sys.IBCSystem.checkEmail;
import hamaster.jpbc.User;
import hamaster.jpbc.dao.UserDAO;
import hamaster.jpbc.sys.IBCSystem;
import hamaster.jpbc.web.Captcha;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.json.JSONObject;

public class UserManager implements ManagerConstraint {

	protected UserDAO dao;

	public UserManager() {
	}

	/**
	 * ?action=checkUsernameAvaiable&username=$username
	 */
	public void checkUsernameAvaiable(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = request.getParameter("username");
		Map<String, String[]> map = request.getParameterMap();
		for (String key0 : map.keySet()) {
			System.out.println(Arrays.toString(map.get(key0)));
		}
		JSONObject jo = new JSONObject(checkExist(username, 1));
		String json = jo.toString();
		response.setContentType("application/json;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		out.println(json);
		out.flush();
		out.close();
	}

	/**
	 * ?action=checkEmailAvaiable&email=$email
	 */
	public void checkEmailAvaiable(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String email = request.getParameter("email");
		JSONObject jo = new JSONObject(checkExist(email, 2));
		String json = jo.toString();
		response.setContentType("application/json;charset=UTF-8");
		response.setCharacterEncoding("UTF-8");
		PrintWriter out = response.getWriter();
		out.println(json);
		out.flush();
		out.close();
	}

	public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String repassword = request.getParameter("repassword");
		String email = request.getParameter("email");
		String captchacode = request.getParameter("captchacode");

		String captcha = (String) request.getSession().getAttribute(Captcha.SIMPLE_CAPCHA_SESSION_KEY);
		if (captcha == null || !captcha.equals(captchacode)) {
			response.sendRedirect("reg.jsp?reason=6");
			return;
		}
		if (!checkUsername(username)) {
			response.sendRedirect("reg.jsp?reason=1");
			return;
		}
		if (password == null || repassword == null || !password.equals(repassword)) {
			response.sendRedirect("reg.jsp?reason=2");
			return;
		}
		if (!checkEmail(email)) {
			response.sendRedirect("reg.jsp?reason=3");
			return;
		}
		if (dao.isUsernameExist(username)) {
			response.sendRedirect("reg.jsp?reason=4");
			return;
		}
		if (dao.isEmailExist(email)) {
			response.sendRedirect("reg.jsp?reason=5");
			return;
		}
		User newUser = new User();
		newUser.setEmail(email);
		newUser.setUsername(username);
		Date now = new Date();
		DateFormat df = new SimpleDateFormat("yyMMddHHmmss");// add salt
		newUser.setPassword(IBCSystem.hash(password + df.format(now)));
		newUser.setRegDate(now);
		
		dao.add(newUser);
		request.getSession().setAttribute("newUser", "true");
		response.sendRedirect("login.jsp?reason=0");
	}

	public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		if (username == null || password == null) {
			response.sendRedirect("login.jsp?reason=1");
			return;
		}
		User user = dao.login(username, password);
		if (user == null) {
			response.sendRedirect("login.jsp?reason=2");
			return;
		}
		HttpSession session = request.getSession(true);
		session.setAttribute("user", user);
		response.sendRedirect("index.jsp");
	}

	public void setDao(UserDAO dao) {
		this.dao = dao;
	}

	private Properties checkExist(String item, int type) {
		if (type == 1) {
			// username
			Properties msg = new Properties();
			if (!checkUsername(item)) {
				msg.setProperty(errcode, String.valueOf(INVALID_USERNAME));
				//用户名中包含非法字符
				msg.setProperty(errmsg, "\u7528\u6237\u540d\u4e2d\u5305\u542b\u975e\u6cd5\u5b57\u7b26");
				return msg;
			}
			if (dao.isUsernameExist(item)) {
				msg.setProperty(errcode, String.valueOf(USERNAME_USED));
				//用户名已被使用
				msg.setProperty(errmsg, "\u7528\u6237\u540d\u5df2\u88ab\u4f7f\u7528");
				return msg;
			}
			msg.setProperty(errcode, String.valueOf(NO_ERROR));
			//用户名可用
			msg.setProperty(errmsg, "\u7528\u6237\u540d\u53ef\u7528");
			return msg;
		}
		if (type == 2) {
			Properties msg = new Properties();
			// email
			if (!checkEmail(item)) {
				msg.setProperty(errcode, String.valueOf(INVALID_EMAIL_ADDR));
				//非法的电子邮件地址
				msg.setProperty(errmsg, "\u975e\u6cd5\u7684\u7535\u5b50\u90ae\u4ef6\u5730\u5740");
				return msg;
			}
			if (dao.isEmailExist(item)) {
				msg.setProperty(errcode, String.valueOf(EMAIL_ADDR_USED));
				//电子邮件地址已经被使用
				msg.setProperty(errmsg, "\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u5df2\u7ecf\u88ab\u4f7f\u7528");
				return msg;
			}
			msg.setProperty(errcode, String.valueOf(NO_ERROR));
			//电子邮件地址可用
			msg.setProperty(errmsg, "\u7535\u5b50\u90ae\u4ef6\u5730\u5740\u53ef\u7528");
			return msg;
		}
		return null;
	}

	private boolean checkUsername(String username) {
		// TODO 判断用户名是否包含非法字符
		return true;
	}
}
